from flask import Blueprint, request, jsonify
from models import Problem, Submission, User, db
from utils import format_response
from decorators import teacher_required, admin_required, get_current_user
from services.llm_service import LLMService
from services.problem_generator import ProblemGenerator
from services.answer_scorer import AnswerScorer
import json
from datetime import datetime

llm_bp = Blueprint('llm', __name__)

# 初始化服务
llm_service = LLMService(provider='deepseek')
problem_generator = ProblemGenerator(llm_service)
answer_scorer = AnswerScorer(llm_service)

@llm_bp.route('/test-connection', methods=['GET'])
@teacher_required
def test_llm_connection():
    """测试LLM连接"""
    try:
        result = llm_service.test_connection()
        return jsonify(format_response(result, "LLM连接测试完成"))
    except Exception as e:
        return jsonify(format_response(message=str(e), code=500)), 500

@llm_bp.route('/generate/code-problem', methods=['POST'])
@teacher_required
def generate_code_problem():
    """生成编程题"""
    try:
        current_user = get_current_user()
        data = request.get_json()
        
        topic = data.get('topic', '基础编程')
        difficulty = data.get('difficulty', 'medium')
        language = data.get('language', 'python')
        knowledge_points = data.get('knowledge_points')
        algorithm_type = data.get('algorithm_type')
        
        if not topic:
            return jsonify(format_response(message="主题不能为空", code=400)), 400
        
        result = problem_generator.generate_problem(
            topic=topic,
            difficulty=difficulty,
            language=language
        )
        
        if result['success']:
            # 可以选择自动保存到数据库
            if data.get('auto_save', False):
                problem_data = result['problem']
                new_problem = Problem(
                    title=problem_data['title'],
                    description=problem_data['description'],
                    type='code',
                    difficulty=problem_data['difficulty'],
                    answer=problem_data.get('solution', {}).get('code', '') if 'solution' in problem_data else problem_data.get('answer', ''),
                    test_cases=json.dumps(problem_data.get('test_cases', [])),
                    input_format=problem_data.get('input_format', ''),
                    output_format=problem_data.get('output_format', ''),
                    points=problem_data.get('points', 10),
                    time_limit=problem_data.get('time_limit', 1000),
                    memory_limit=problem_data.get('memory_limit', 64),
                    language=problem_data.get('language', language),
                    created_by=current_user.id
                )
                db.session.add(new_problem)
                db.session.commit()
                
                result['saved_problem_id'] = new_problem.id
        
        return jsonify(format_response(result, "编程题生成完成"))
        
    except Exception as e:
        import traceback
        print(f"生成编程题异常: {str(e)}")
        print(f"异常详情: {traceback.format_exc()}")
        return jsonify(format_response(message=f"生成题目失败: {str(e)}", code=500)), 500

@llm_bp.route('/generate/choice-problem', methods=['POST'])
@teacher_required
def generate_choice_problem():
    """生成选择题"""
    try:
        current_user = get_current_user()
        data = request.get_json()
        
        topic = data.get('topic', '基础概念')
        difficulty = data.get('difficulty', 'medium')
        question_type = data.get('question_type', 'single')
        option_count = data.get('option_count', 4)
        knowledge_point = data.get('knowledge_point')
        
        if not topic:
            return jsonify(format_response(message="主题不能为空", code=400)), 400
        
        result = problem_generator.generate_choice_problem(
            topic=topic,
            difficulty=difficulty,
            question_type=question_type,
            option_count=option_count
        )
        
        if result['success'] and data.get('auto_save', False):
            problem_data = result['problem']
            new_problem = Problem(
                title=problem_data['title'],
                description=problem_data['description'],
                type='choice',
                difficulty=problem_data['difficulty'],
                answer=problem_data['answer'],
                options=json.dumps(problem_data.get('options', [])),
                points=problem_data.get('points', 5),
                created_by=current_user.id
            )
            db.session.add(new_problem)
            db.session.commit()
            result['saved_problem_id'] = new_problem.id
        
        return jsonify(format_response(result, "选择题生成完成"))
        
    except Exception as e:
        return jsonify(format_response(message=str(e), code=500)), 500

@llm_bp.route('/generate/blank-problem', methods=['POST'])
@teacher_required
def generate_blank_problem():
    """生成填空题"""
    try:
        current_user = get_current_user()
        data = request.get_json()
        
        topic = data.get('topic', '基础概念')
        difficulty = data.get('difficulty', 'medium')
        blank_count = data.get('blank_count', 3)
        
        if not topic:
            return jsonify(format_response(message="主题不能为空", code=400)), 400
        
        result = problem_generator.generate_blank_problem(
            topic=topic,
            difficulty=difficulty,
            blank_count=blank_count
        )
        
        if result['success'] and data.get('auto_save', False):
            problem_data = result['problem']
            new_problem = Problem(
                title=problem_data['title'],
                description=problem_data['description'],
                type='blank',
                difficulty=problem_data['difficulty'],
                answer=problem_data['answer'],
                points=problem_data.get('points', 5),
                created_by=current_user.id
            )
            db.session.add(new_problem)
            db.session.commit()
            result['saved_problem_id'] = new_problem.id
        
        return jsonify(format_response(result, "填空题生成完成"))
        
    except Exception as e:
        return jsonify(format_response(message=str(e), code=500)), 500

@llm_bp.route('/generate/short-problem', methods=['POST'])
@teacher_required
def generate_short_problem():
    """生成简答题"""
    try:
        current_user = get_current_user()
        data = request.get_json()
        
        topic = data.get('topic', '概念理解')
        difficulty = data.get('difficulty', 'medium')
        question_type = data.get('question_type', 'concept')
        
        if not topic:
            return jsonify(format_response(message="主题不能为空", code=400)), 400
        
        result = problem_generator.generate_short_problem(
            topic=topic,
            difficulty=difficulty,
            question_type=question_type
        )
        
        if result['success'] and data.get('auto_save', False):
            problem_data = result['problem']
            new_problem = Problem(
                title=problem_data['title'],
                description=problem_data['description'],
                type='short',
                difficulty=problem_data['difficulty'],
                answer=problem_data['answer'],
                points=problem_data.get('points', 10),
                created_by=current_user.id
            )
            db.session.add(new_problem)
            db.session.commit()
            result['saved_problem_id'] = new_problem.id
        
        return jsonify(format_response(result, "简答题生成完成"))
        
    except Exception as e:
        return jsonify(format_response(message=str(e), code=500)), 500

@llm_bp.route('/generate/batch', methods=['POST'])
@teacher_required
def batch_generate_problems():
    """批量生成题目"""
    try:
        current_user = get_current_user()
        data = request.get_json()
        
        course_topic = data.get('course_topic', '编程基础')
        problem_types = data.get('problem_types', ['code', 'choice'])
        difficulty_distribution = data.get('difficulty_distribution', {
            'easy': 0.3,
            'medium': 0.5,
            'hard': 0.2
        })
        count_requirements = data.get('count_requirements', {
            'code': 3,
            'choice': 5,
            'blank': 2,
            'short': 2
        })
        
        if not course_topic:
            return jsonify(format_response(message="课程主题不能为空", code=400)), 400
        
        result = problem_generator.batch_generate_problems(
            course_topic=course_topic,
            problem_types=problem_types,
            difficulty_distribution=difficulty_distribution,
            count_requirements=count_requirements
        )
        
        if result['success'] and data.get('auto_save', False):
            saved_problems = []
            for problem_data in result['problems']:
                new_problem = Problem(
                    title=problem_data['title'],
                    description=problem_data['description'],
                    type=problem_data['type'],
                    difficulty=problem_data['difficulty'],
                    answer=problem_data['answer'],
                    test_cases=json.dumps(problem_data.get('test_cases', [])),
                    options=json.dumps(problem_data.get('options', [])),
                    points=problem_data.get('points', 10),
                    created_by=current_user.id
                )
                db.session.add(new_problem)
                saved_problems.append(new_problem.id)
            
            db.session.commit()
            result['saved_problem_ids'] = saved_problems
        
        return jsonify(format_response(result, "批量题目生成完成"))
        
    except Exception as e:
        return jsonify(format_response(message=str(e), code=500)), 500

@llm_bp.route('/score/code', methods=['POST'])
@teacher_required
def score_code_answer():
    """评分编程题答案"""
    try:
        data = request.get_json()
        
        problem_description = data.get('problem_description')
        standard_answer = data.get('standard_answer')
        student_answer = data.get('student_answer')
        language = data.get('language', 'python')
        test_cases = data.get('test_cases', [])
        
        if not all([problem_description, standard_answer, student_answer]):
            return jsonify(format_response(message="题目描述、标准答案和学生答案不能为空", code=400)), 400
        
        result = answer_scorer.score_code_answer(
            problem_description=problem_description,
            standard_answer=standard_answer,
            student_answer=student_answer,
            language=language,
            test_cases=test_cases
        )
        
        return jsonify(format_response(result, "编程题评分完成"))
        
    except Exception as e:
        return jsonify(format_response(message=str(e), code=500)), 500

@llm_bp.route('/score/choice', methods=['POST'])
@teacher_required
def score_choice_answer():
    """评分选择题答案"""
    try:
        data = request.get_json()
        
        question = data.get('question')
        correct_answer = data.get('correct_answer')
        student_answer = data.get('student_answer')
        
        if not all([question, correct_answer, student_answer]):
            return jsonify(format_response(message="题目、正确答案和学生答案不能为空", code=400)), 400
        
        result = answer_scorer.score_choice_answer(
            question=question,
            correct_answer=correct_answer,
            student_answer=student_answer
        )
        
        return jsonify(format_response(result, "选择题评分完成"))
        
    except Exception as e:
        return jsonify(format_response(message=str(e), code=500)), 500

@llm_bp.route('/score/blank', methods=['POST'])
@teacher_required
def score_blank_answer():
    """评分填空题答案"""
    try:
        data = request.get_json()
        
        question = data.get('question')
        standard_answer = data.get('standard_answer')
        student_answer = data.get('student_answer')
        
        if not all([question, standard_answer, student_answer]):
            return jsonify(format_response(message="题目、标准答案和学生答案不能为空", code=400)), 400
        
        result = answer_scorer.score_blank_answer(
            question=question,
            standard_answer=standard_answer,
            student_answer=student_answer
        )
        
        return jsonify(format_response(result, "填空题评分完成"))
        
    except Exception as e:
        return jsonify(format_response(message=str(e), code=500)), 500

@llm_bp.route('/score/short', methods=['POST'])
@teacher_required
def score_short_answer():
    """评分简答题答案"""
    try:
        data = request.get_json()
        
        question = data.get('question')
        reference_answer = data.get('reference_answer')
        student_answer = data.get('student_answer')
        scoring_criteria = data.get('scoring_criteria', [])
        
        if not all([question, reference_answer, student_answer]):
            return jsonify(format_response(message="题目、参考答案和学生答案不能为空", code=400)), 400
        
        result = answer_scorer.score_short_answer(
            question=question,
            reference_answer=reference_answer,
            student_answer=student_answer,
            scoring_criteria=scoring_criteria
        )
        
        return jsonify(format_response(result, "简答题评分完成"))
        
    except Exception as e:
        return jsonify(format_response(message=str(e), code=500)), 500

@llm_bp.route('/score/batch', methods=['POST'])
@teacher_required
def batch_score_answers():
    """批量评分答案"""
    try:
        data = request.get_json()
        submissions = data.get('submissions', [])
        
        if not submissions:
            return jsonify(format_response(message="提交列表不能为空", code=400)), 400
        
        result = answer_scorer.batch_score_answers(submissions)
        
        return jsonify(format_response(result, "批量评分完成"))
        
    except Exception as e:
        return jsonify(format_response(message=str(e), code=500)), 500

@llm_bp.route('/stats', methods=['GET'])
@teacher_required
def get_llm_stats():
    """获取LLM服务统计信息"""
    try:
        stats = {
            'llm_service': llm_service.get_provider_info(),
            'problem_generator': problem_generator.get_generation_stats(),
            'answer_scorer': answer_scorer.get_scoring_stats()
        }
        
        return jsonify(format_response(stats, "LLM服务统计信息"))
        
    except Exception as e:
        return jsonify(format_response(message=str(e), code=500)), 500
